package com.song.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;

import com.aliyun.oss.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Component
public class AliyunOSSOperator {
    @Autowired private AliyunOSSProperties aliyunOSSProperties;
   public String uploadFile( MultipartFile file) throws com.aliyuncs.exceptions.ClientException, IOException {
       String endpoint = aliyunOSSProperties.getEndpoint();
       String bucketName = aliyunOSSProperties.getBucketName();
       String region = aliyunOSSProperties.getRegion();

       // 从环境变量中获取访问凭证。
       EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
       //根据传入的文件生成一个唯一的objectName
       //获取当前系统日期字符串
       String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
       //生成新的文件名 = 唯一id + 文件后缀
       String newFileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
       // 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
       String objectName = dir + "/" + newFileName;
       InputStream inputStream = file.getInputStream();
       // 创建OSSClient实例。
       // 当OSSClient实例不再使用时，调用shutdown方法以释放资源。
       ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
       clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
       OSS ossClient = OSSClientBuilder.create()
               .endpoint(endpoint)
               .credentialsProvider(credentialsProvider)
               .clientConfiguration(clientBuilderConfiguration)
               .region(region)
               .build();

       try {
           // 创建PutObjectRequest对象。
           PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(inputStream.readAllBytes()));
           // 如果需要上传时设置存储类型和访问权限，请参考以下示例代码。
           // ObjectMetadata metadata = new ObjectMetadata();
           // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
           // metadata.setObjectAcl(CannedAccessControlList.Private);
           // putObjectRequest.setMetadata(metadata);

           // 上传文件。
           PutObjectResult result = ossClient.putObject(putObjectRequest);
       } catch (OSSException oe) {
           System.out.println("Caught an OSSException, which means your request made it to OSS, "
                   + "but was rejected with an error response for some reason.");
           System.out.println("Error Message:" + oe.getErrorMessage());
           System.out.println("Error Code:" + oe.getErrorCode());
           System.out.println("Request ID:" + oe.getRequestId());
           System.out.println("Host ID:" + oe.getHostId());
       } catch (ClientException ce) {
           System.out.println("Caught an ClientException, which means the client encountered "
                   + "a serious internal problem while trying to communicate with OSS, "
                   + "such as not being able to access the network.");
           System.out.println("Error Message:" + ce.getMessage());
       } finally {
           if (ossClient != null) {
               ossClient.shutdown();
           }
       }
       //返回上传后的文件的url
       return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;
   }
}
